﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System.Windows;
using System.Windows.Media.Animation;

namespace Xceed.Silverlight.ListBox
{
  internal class SizeAnimation : DependencyObject, IAnimation
  {
    #region WidthChange Property

    internal static readonly DependencyProperty WidthChangeProperty = DependencyProperty.Register(
      "WidthChange",
      typeof( double ),
      typeof( SizeAnimation ),
      new PropertyMetadata( ( double )0.0d ) );

    internal double WidthChange
    {
      get
      {
        return ( double )this.GetValue( SizeAnimation.WidthChangeProperty );
      }
      set
      {
        this.SetValue( SizeAnimation.WidthChangeProperty, value );
      }
    }

    #endregion

    #region HeightChange Property

    internal static readonly DependencyProperty HeightChangeProperty = DependencyProperty.Register(
      "HeightChange",
      typeof( double ),
      typeof( SizeAnimation ),
      new PropertyMetadata( ( double )0.0d ) );

    internal double HeightChange
    {
      get
      {
        return ( double )this.GetValue( SizeAnimation.HeightChangeProperty );
      }
      set
      {
        this.SetValue( SizeAnimation.HeightChangeProperty, value );
      }
    }

    #endregion

    #region ActualWidthChange Property

    internal static readonly DependencyProperty ActualWidthChangeProperty = DependencyProperty.Register(
      "ActualWidthChange",
      typeof( double ),
      typeof( SizeAnimation ),
      new PropertyMetadata( ( double )0.0d ) );

    internal double ActualWidthChange
    {
      get
      {
        return ( double )this.GetValue( SizeAnimation.ActualWidthChangeProperty );
      }
      set
      {
        this.SetValue( SizeAnimation.ActualWidthChangeProperty, value );
      }
    }

    #endregion

    #region ActualHeightChange Property

    internal static readonly DependencyProperty ActualHeightChangeProperty = DependencyProperty.Register(
      "ActualHeightChange",
      typeof( double ),
      typeof( SizeAnimation ),
      new PropertyMetadata( ( double )0.0d ) );

    internal double ActualHeightChange
    {
      get
      {
        return ( double )this.GetValue( SizeAnimation.ActualHeightChangeProperty );
      }
      set
      {
        this.SetValue( SizeAnimation.ActualHeightChangeProperty, value );
      }
    }

    #endregion

    #region MaximumWidthChange Property

    internal static readonly DependencyProperty MaximumWidthChangeProperty = DependencyProperty.Register(
      "MaximumWidthChange",
      typeof( double ),
      typeof( SizeAnimation ),
      new PropertyMetadata( ( double )0.0d ) );

    internal double MaximumWidthChange
    {
      get
      {
        return ( double )this.GetValue( SizeAnimation.MaximumWidthChangeProperty );
      }
      set
      {
        this.SetValue( SizeAnimation.MaximumWidthChangeProperty, value );
      }
    }

    #endregion

    #region MaximumHeightChange Property

    internal static readonly DependencyProperty MaximumHeightChangeProperty = DependencyProperty.Register(
      "MaximumHeightChange",
      typeof( double ),
      typeof( SizeAnimation ),
      new PropertyMetadata( ( double )0.0d ) );

    internal double MaximumHeightChange
    {
      get
      {
        return ( double )this.GetValue( SizeAnimation.MaximumHeightChangeProperty );
      }
      set
      {
        this.SetValue( SizeAnimation.MaximumHeightChangeProperty, value );
      }
    }

    #endregion

    #region ActualMaximumWidthChange Property

    internal static readonly DependencyProperty ActualMaximumWidthChangeProperty = DependencyProperty.Register(
      "ActualMaximumWidthChange",
      typeof( double ),
      typeof( SizeAnimation ),
      new PropertyMetadata( ( double )0.0d ) );

    internal double ActualMaximumWidthChange
    {
      get
      {
        return ( double )this.GetValue( SizeAnimation.ActualMaximumWidthChangeProperty );
      }
      set
      {
        this.SetValue( SizeAnimation.ActualMaximumWidthChangeProperty, value );
      }
    }

    #endregion

    #region ActualMaximumHeightChange Property

    internal static readonly DependencyProperty ActualMaximumHeightChangeProperty = DependencyProperty.Register(
      "ActualMaximumHeightChange",
      typeof( double ),
      typeof( SizeAnimation ),
      new PropertyMetadata( ( double )0.0d ) );

    internal double ActualMaximumHeightChange
    {
      get
      {
        return ( double )this.GetValue( SizeAnimation.ActualMaximumHeightChangeProperty );
      }
      set
      {
        this.SetValue( SizeAnimation.ActualMaximumHeightChangeProperty, value );
      }
    }

    #endregion

    #region IAnimation Implementation

    AnimationDirection IAnimation.AnimationDirection
    {
      get
      {
        return m_animationDirection;
      }
      set
      {
        if( m_animationDirection != value )
        {
          m_animationDirection = value;
        }
      }
    }


    IEasingFunction IAnimation.EasingFunction
    {
      get
      {
        return m_easingFunction;
      }
      set
      {
        if( m_easingFunction != value )
        {
          m_easingFunction = value;
        }
      }
    }

    TransitionAnimation IAnimation.ParentTransition
    {
      get
      {
        return m_parentTransition;
      }
      set
      {
        if( m_parentTransition != value )
        {
          m_parentTransition = value;
        }
      }
    }

    void IAnimation.ComputeAnimationUpdate( double normalizedTime )
    {
      double easedTime = normalizedTime;
      if( m_easingFunction != null )
      {
        easedTime = m_easingFunction.Ease( normalizedTime );
      }

      if( m_animationDirection == AnimationDirection.ToReferencePosition )
      {
        if( !double.IsNaN( this.WidthChange ) )
        {
          this.ActualWidthChange = this.WidthChange - ( easedTime * this.WidthChange );
        }

        if( !double.IsNaN( this.HeightChange ) )
        {
          this.ActualHeightChange = this.HeightChange - ( easedTime * this.HeightChange );
        }

        if( !double.IsNaN( this.MaximumWidthChange ) )
        {
          this.ActualMaximumWidthChange = this.MaximumWidthChange - ( easedTime * this.MaximumWidthChange );
        }

        if( !double.IsNaN( this.MaximumHeightChange ) )
        {
          this.ActualMaximumHeightChange = this.MaximumHeightChange - ( easedTime * this.MaximumHeightChange );
        }
      }
      else
      {
        if( !double.IsNaN( this.WidthChange ) )
        {
          this.ActualWidthChange = easedTime * this.WidthChange;
        }

        if( !double.IsNaN( this.HeightChange ) )
        {
          this.ActualHeightChange = easedTime * this.HeightChange ;
        }

        if( !double.IsNaN( this.MaximumWidthChange ) )
        {
          this.ActualMaximumWidthChange = easedTime * this.MaximumWidthChange ;
        }

        if( !double.IsNaN( this.MaximumHeightChange ) )
        {
          this.ActualMaximumHeightChange = easedTime * this.MaximumHeightChange;
        }

      }
    }

    #endregion

    #region Private Members

    internal static SizeAnimation DefaultSizeAnimation = new SizeAnimation();
    private TransitionAnimation m_parentTransition = null;
    private IEasingFunction m_easingFunction = null;
    private AnimationDirection m_animationDirection = AnimationDirection.ToReferencePosition;
    #endregion
  }
}
